package org.epidroid.epidroid.chronos.engine.parsers;

import java.io.IOException;
import java.io.StringReader;
import java.util.ArrayList;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;

import org.epidroid.epidroid.chronos.engine.Chronos;
import org.epidroid.epidroid.chronos.engine.objects.ChronosNode;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;

import android.util.Log;

public class MenuParser {

	public static ChronosNode parse(String input, String name) {
		DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
		DocumentBuilder builder = null;
		try {
			builder = dbf.newDocumentBuilder();
		} catch (ParserConfigurationException e) {
			Log.e(Chronos.LOGCAT, e.getMessage());
			return null;
		}
		Document dom = null;

		InputSource inStream = new InputSource();
		inStream.setCharacterStream(new StringReader(input));
		try {
			dom = builder.parse(inStream);
		} catch (SAXException e) {
			Log.e(Chronos.LOGCAT, e.getMessage());
			e.printStackTrace();
			return null;
		} catch (IOException e) {
			Log.e(Chronos.LOGCAT, e.getMessage());
			e.printStackTrace();
			return null;
		}

		Element root = dom.getDocumentElement();
		ArrayList<ChronosNode> nodes = getNodes(root);
		ChronosNode rootNode = new ChronosNode("0", name);
		rootNode.setNodes(nodes);
		return rootNode;
	}


	/*
	 * item: <node>...</node> This function assumes that the subnodes are in the
	 * following order: id, name, nodes
	 */
	private static ChronosNode getNode(Node node) {

		String name = null;
		String id = null;
		ArrayList<ChronosNode> childs = null;

		NodeList list = node.getChildNodes();
		for (int i = 0; i < list.getLength(); i++) {
			Node item = list.item(i);
			if (item == null)
				continue;
			if ((item.getNodeName().equals("id")) && (item instanceof Element)) {
				id = ((Element) item).getTextContent();
			} else if (item.getNodeName().equals("name")
					&& (item instanceof Element)) {
				name = ((Element) item).getTextContent();
			} else if (item.getNodeName().equals("nodes")) {
				childs = getNodes(item);
			}
		}

		if (name == null) {
			Log.e(Chronos.LOGCAT, "Missing name");
			return null;
		} else if (id == null) {
			Log.e(Chronos.LOGCAT, "Missing id");
			return null;
		}
		ChronosNode res = new ChronosNode(id, name);
		if (childs != null) {
			res.setNodes(childs);
		}

		return res;
	}

	/*
	 * parent: <nodes>...</nodes>
	 */
	private static ArrayList<ChronosNode> getNodes(Node parent) {
		ArrayList<ChronosNode> res = new ArrayList<ChronosNode>();

		NodeList list = parent.getChildNodes();
		for (int i = 0; i < list.getLength(); i++) {
			Node child = list.item(i);
			if ((child != null) && (child.getNodeName().equals("node"))) {
				ChronosNode curNode = getNode(child);
				res.add(curNode);
			}
		}

		return res;
	}
}
